package com.learn.learnsystem.utils;

import cn.hutool.core.util.StrUtil;
import io.jsonwebtoken.ExpiredJwtException;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.MalformedJwtException;
import io.jsonwebtoken.SignatureAlgorithm;
import io.jsonwebtoken.security.Keys;
import io.jsonwebtoken.security.SecurityException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.stereotype.Component;

import javax.crypto.SecretKey;
import java.util.Base64;
import java.util.Date;

@Component
public class JwtTokenUtil {

    @Autowired
    private StringRedisTemplate stringRedisTemplate;
    // 使用新的 MacAlgorithm 常量
    private SecretKey secretKey;
    private static final long ACCESS_EXPIRE = 30 * 60 * 1000; // 30分钟

    private static final long REFRESH_EXPIRE = 7 * 24 * 60 * 60 * 1000; // 7天


    public String generateToken(UserDetails userDetails) {
        String secretString = (String) stringRedisTemplate.opsForHash().get("login:secretKey", userDetails.getUsername());
        if (StrUtil.isBlank(secretString)) {
            secretKey = Keys.secretKeyFor(SignatureAlgorithm.HS256);
            String decode = decode(secretKey);
            stringRedisTemplate.opsForHash().put("login:secretKey", userDetails.getUsername(), decode);
        } else {
            secretKey = encode(secretString);
        }
        return Jwts.builder()
                .subject(userDetails.getUsername())
                .issuedAt(new Date())
                .expiration(new Date(System.currentTimeMillis() + ACCESS_EXPIRE))
                .signWith(secretKey, Jwts.SIG.HS256) // 新版签名方法
                .compact();
    }

    // 生成RefreshToken
    public String generateRefreshToken(UserDetails userDetails) {
        return Jwts.builder()
                .subject(userDetails.getUsername())
                .issuedAt(new Date())
                .expiration(new Date(System.currentTimeMillis() + ACCESS_EXPIRE))
                .signWith(secretKey, Jwts.SIG.HS256) // 新版签名方法
                .compact();
    }

    private SecretKey encode(String secretString) {
        byte[] decodedKey = Base64.getDecoder().decode(secretString);
        SecretKey secret = Keys.hmacShaKeyFor(decodedKey);
        return secret;
    }

    private String decode(SecretKey secretKey) {
        // 1. 获取密钥的字节数组
        byte[] keyBytes = secretKey.getEncoded();

        // 2. 转换为 Base64 字符串
        String base64Key = Base64.getEncoder().encodeToString(keyBytes);
        return base64Key;
    }

    public boolean validateToken(String token) {
        try {
            Jwts.parser()
                    .verifyWith(secretKey)
                    .build()
                    .parseSignedClaims(token);
            return true;
        } catch (SecurityException | MalformedJwtException | ExpiredJwtException e) {
            // 分别处理不同类型的异常
            return false;
        }
    }

    public String getUsernameFromToken(String token) {
        return Jwts.parser()
                .verifyWith(secretKey)
                .build()
                .parseSignedClaims(token)
                .getPayload()
                .getSubject();
    }

    public long getAccessExpiration() {
        return ACCESS_EXPIRE;
    }

    public long getRefreshExpiration() {
        return REFRESH_EXPIRE;
    }
}